STM8 Timer 2 - Zeitbasis
Die Nutzung eines Timers als primäre Zeitsteuerung eines Betriebssystems oder Kernels oder im einfachsten Fall für eine zeitliche Ablaufsteuerung innerhalb einer Anwendung, ist eine übliche Aufgabe. Diese kurze Beschreibung soll einen einfachen Überblick geben wie vorzugehen ist um dieses Ziel mit einem STM8 und dessen Timer 2 zu erreichen.
Mit Hilfe des Timer 2 (natürlich kann auch jeder andere Timer auf dem STM8 verwendet werden) kann eine Zeitbasis für eine STM8 Software eingerichtet werden. Als Schnittstellen für die Anwendung sollen die folgenden globalen Variablen bereitstellt werden die von der S/W-Anwendung abgefragt werden können:
Alle Variablen werden wegen des schnellen und einfachen Zugriffs im RAM0 angelegt wo sie mit Befehlen mit einer nur 1 Byte langen Adresse angesprochen werden können. Dies ist aber keine zwingende Vorgabe da auch Variablen im „normalen“ RAM-Bereich (`ram1´) möglich sind.
|
Für die weitere Initialisierungen des Timers wird von einem 16 MHz Takt für fMASTER ausgegangen, der entweder vom HSI (High Speed Internal RC Oszillator) oder vom HSE (High Speed External Quarz Oszillator) bereit gestellt wird.
Folgende Initialisierungs-Sequenz wird nur für den HSE mit externem Quarz benötigt!
![]() |
Alternativ kann auch der HSI als Taktquelle verwendet werden. Dazu wird die nachfolgende Sequenz statt der HSE Sequenz in die Initialisierung eingefügt.
Der HSI ist sozusagen der Standard-Oszillator im STM8, der nach einem Reset automatisch aktiviert wird. Durch den „High Speed Internal Clock Prescaler“ im Register CLK_CKDIVR wird dessen Frequenz nach einem Reset aber durch 128 geteilt (125 kHz). Daher muß der Prescaler auf den Teiler-Faktor 1 umgestellt werden.
![]() |
Mit dieser Einstellung wird die HSI Frequenz durch den Faktor 1 geteilt und liefert die gewünschten 16 MHz an den Vorteiler des Timer 2.
Der Timer 2 besitzt einen eigenen Vorteiler der für den gewünschten Zweck dieser Zeitbasis auf einen Teiler-Faktor von 1024 eingestellt wird. Der Timer 2 Prescaler ist nicht frei programmierbar sondern ermöglicht nur Teiler-Faktoren von
1 / 2 (PSC[3..0])
gesetzt durch die PSC[3..0] Bits im Register TIM2_PSCR.

Mit der gewählten Einstellung des Vorteilers ergibt sich ein CK_CNT von 16MHz / 512 = 31,250 kHz als Zählerfrequenz für den Timer 2. Dieser Frequenz von 31,250 kHz entspricht eine minimale Zeitauflösung von 1/31250 = 32µsec.

Da als Ziel ein 100msec Interrupt vorgegeben ist muß das Auto-Reload Register des Timer 2 mit einem Wert von 100msec/32µsec = 3125 entspricht hexadezimal 0x0C35h, geladen werden um die 100 msec zu erzielen.
Der Zähler zählt damit von 0 bis 3125 da im Auto-Reload Register dieser Wert eingetragen ist. Durch den Gleichstand (match) von Zähler und Auto-Reload Register wird ein Zähler Reset durchgeführt.
Die Zeitbasis soll mit möglichst wenig Software Unterstützung funktionieren, daher wird der Timer 2 als freilaufender Timer initialisiert und der Update Event (Überlauf) erzeugt einen Timer 2 Interrupt.
In nachfolgendem Programm Listing sind die oben erarbeiteten Werte verwendet um den Timer 2 entsprechend zu konfigurieren.
![]() |
Nach der Initialisierung des Timer 2 wird nun alle 100 ms ein „Timer2 Overflow Interrupt“ erzeugt der auf den Interrupt Vector irq13 verzweigt und damit die Adresse „Timer2Interrupt“ als Einsprungadresse nutzt.
Wie beim STM8 üblich besteht jeder Interrupt Vector aus 4 Byte, wobei das erste Byte 0x82h den Maschinenbefehl „INT“ darstellt und die darauf folgenden drei Bytes eine lange 3 Byte Adresse (far) die vom Assembler als relative Adresse „Timer2Interrupt.l“ geführt wird und erst bei einem Link-Vorgang während des „assemblierens“ eine absolute Adresse im Speicher für die Interrupt Subroutine anlegt.
![]() |
Verzweigt der Prozessor durch den ausgelösten Hardware-Interrupt auf die Addresse „Timer2Interrupt.l“ ( „.l“ steht für eine „lange 3 Byte Adresse“), so findet er an dieser Stelle die Interrupt Subroutine für den Timer2 Interrupt.
Die nachfolgend gelistete Interrupt Subroutine verwaltet die Informationen zur Übergabe in den Variablen TFLAG, SECFLAG und BITTEST.
![]() |
Natürlich kann die Funktion dieser Subroutine an die Anforderungen angepasst werden.
Wie bereits beschrieben ist „Timer2Interrupt.l“ die Einsprungadresse (Label) für die Timer2 Interrupt Routine.
Als erste Aktion werden alle Interrupts global gesperrt um ein intensives „Nesting“ von Interrupts zu vermeiden. Dazu sollte die Interrupt Routine so kurz wie möglich sein.
Im Folgenden wird das TFLAG inkrementiert und auf den Wert 10 getestet. TFLAG soll von 0 bis 9 zählen um das SECFLAG jede Sekunde zu inkrementieren. Mit diesen beiden Variablen stehen der Anwendung zwei Indikatoren zur Verfügung. Zum Einen ein 100ms Signal (TFLAG) das für schnelle Zeitabläufe innerhalb der Anwendung genutzt werden kann und ein 1 Sekunden Signal (SECFLAG) das für eine Uhrzeit oder für langsame zeitliche Effekte im Zusammenwirken mit einer Software-Applikation von Vorteil sein wird.
Zur Visualsierung der Funktion dieser Zeitbasis wurde zusätzlich die Toggle-Funktion für ein GPIO oder eine LED implementiert.
TOGG_END ist die Sprungmarke für das Beenden der Interrupt Subroutine. Ab diesem Punkt werden alle Interrupts global wieder freigegeben (rim) und schließlich erfolgt der Rücksprung (iret) in den normalen Kontext.
Dieses Dokument sowie dessen Inhalt, insbesondere Texte, Fotografien und Grafiken, unterliegt dem Copyright (© 2017) und sind nur mit einer schriftlicher Zustimmung des Autors, Dipl.Ing.(FH) Franz Henkel zur vollständigen oder auszugsweisen Weiterverwendung in Form einer gedruckten oder elektronischen Kopie oder Replikation bzw. einer vollständigen oder auszugsweisen Bereitstellung des Inhalts in schriftlicher oder elektronischer Form, zu verwenden.